﻿/****************************** Module Header ******************************\
 * Module Name:  mxControl.cs
 * Module Version:  1.0.0 (2012-8-25)
 * Copyright (c) AnyEB.Com (14507247@qq.com)
 * 
 * This class is used to extension winformcontrol instance's method.  It supplies 
 * public static extension methods to load data or get othor control.
 * 
 * This source is subject to the GPL License.
 * See http://www.gnu.org/licenses/gpl.html.
 * All other rights reserved.
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace UCL.Forms
{
    public static class mxControl
    {
        /// <summary>
        /// 控件集转换成控件列表
        /// </summary>
        /// <param name="cc"></param>
        /// <param name="filters">要过滤的控件类型</param>
        /// <returns></returns>
        public static IList<Control> ToList(this Control.ControlCollection cc, params Type[] filters)
        {
            IList<Control> list = new List<Control>();
            foreach (Control c in cc)
            {
                if (filters != null && filters.Contains(c.GetType())) continue;
                list.Add(c);
            }
            return list;
        }

        /// <summary>
        /// 遍历获取所有子控件
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        public static IList<Control> GetChildControlsByNamePrefix(this Control c, string[] filter = null, string namePrefix = "tb", int deep = 99)
        {
            IList<Control> list = new List<Control>();
            c.GetChildControlsFnc(ref list, filter, namePrefix, deep);
            return list;
        }

        // 遍历获取所有子控件(核心算法)
        private static void GetChildControlsFnc(this Control c, ref IList<Control> cc, string[] filter = null, string namePrefix = "tb", int deep = 99, int loopcount = 0)
        {
            if (loopcount >= deep) return;
            foreach (Control sc in c.Controls)
            {
                if ((filter != null && filter.Contains(sc.Name)) || sc.GetType() == typeof(DataGridView)) continue;
                if (sc.Name.StartsWith(namePrefix)) cc.Add(sc);
                if (sc.HasChildren) sc.GetChildControlsFnc(ref cc, filter, namePrefix, deep, loopcount + 1);
            }
        }

        /// <summary>
        /// 遍历子控件查找指定名称的控件 2013-2-1 by sutroon
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="c"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static T FindControlByName<T>(this Control c, string name) where T : Control
        {
            T t = null;
            c.FindControlByNameFunc<T>(ref t, name);
            return t;

        }
        // 遍历子控件查找指定名称的控件(核心算法)
        private static void FindControlByNameFunc<T>(this Control c, ref T t, string name) where T : Control
        {
            foreach (Control c1 in c.Controls)
            {
                if (c1.Name == name && c1.GetType() == typeof(T))
                {
                    t = (T)c1;
                    return;
                }
                if (c1.HasChildren) c1.FindControlByNameFunc<T>(ref t, name);
            }
        }

        /// <summary>
        /// 遍历寻找指定控件的窗体
        /// <para>2013-5-11 by sutroon</para>
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        public static Form FindForm(this Control c)
        {
            if (c.GetType().BaseType == typeof(Form)) return (Form)c;
            c.Parent.FindForm();
            return null;
        }

        /// <summary>
        /// 弹出打开文件操作对话框
        /// <para>2013-6-22 created,2013-6-24 by sutroon ShowSaveFileDialog改成泛型</para>
        /// <para>2013-8-24 新增act和successDiaMsg</para>
        /// <para>2013-8-28 泛型改类型</para>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="c"></param>
        /// <param name="filter"></param>
        /// <param name="act"></param>
        /// <returns></returns>
        public static string ShowOpenFileDialog(this Control c, string filter = "All files (*.*)|*.*", Action<string> act = null)
        {
            switch (filter.ToLower())
            {
                case "excel":
                    filter = "Excel files (*.xls)|*.xls";
                    break;
                case "txt":
                    filter = "Txt files (*.txt)|*.txt";
                    break;
                case "xml":
                    filter = "Xml files (*.xml)|*.xml";
                    break;
                default:
                    filter = "All files (*.*)|*.*";
                    break;
            }
            OpenFileDialog fd = new OpenFileDialog() { Filter = filter, CheckFileExists = true };
            if (DialogResult.OK != fd.ShowDialog()) return string.Empty;
            if (act != null)
            {
                act(fd.FileName);
            }
            return fd.FileName;
        }

        /// <summary>
        /// 弹出保存文件操作对话框
        /// <para>2013-8-28 created</para>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="c"></param>
        /// <param name="filter"></param>
        /// <param name="act"></param>
        /// <param name="successDiaMsg">如：导出成功,是否打开保存目录?</param>
        /// <returns></returns>
        public static string ShowSaveFileDialog(this Control c, string filter = "All files (*.*)|*.*", Func<string, string> act = null, string successDiaMsg = "导出成功，是否打开文件目录?")
        {
            switch (filter.ToLower())
            {
                case "excel":
                    filter = "Excel files (*.xls)|*.xls";
                    break;
                case "txt":
                    filter = "Txt files (*.txt)|*.txt";
                    break;
                case "xml":
                    filter = "Xml files (*.xml)|*.xml";
                    break;
            }
            SaveFileDialog fd = new SaveFileDialog() { Filter = filter, CreatePrompt = true };
            if (DialogResult.OK != fd.ShowDialog()) return string.Empty;
            if (act != null)
            {
                string msg = act(fd.FileName);
                if (msg.ToLower() == "success")
                {
                    if (!string.IsNullOrEmpty(successDiaMsg))
                    {
                        if (DialogResult.OK != MessageBox.Show(successDiaMsg, "提示", MessageBoxButtons.OKCancel)) return fd.FileName;
                        System.Diagnostics.Process.Start(System.IO.Path.GetDirectoryName(fd.FileName));
                    }
                }
                else
                {
                    MessageBox.Show(msg);
                    return string.Empty;
                }
            }
            return fd.FileName;
        }
    }
}
